package com.ceyear.my_idcard;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class HttpUtils {

    private static OkHttpClient getUnsafeOkHttpClient() {
        try {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        }

                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

            // Create an ssl socket factory with our all-trusting manager
            final okhttp3.OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });

            return builder.build();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String doGet(String host, String path, Map<String, String> headers, Map<String, String> querys) throws IOException {
        OkHttpClient client = getUnsafeOkHttpClient();

        Request.Builder builder = new Request.Builder();
        builder.url(buildUrl(host, path, querys));
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            builder.addHeader(entry.getKey(), entry.getValue());
        }

        Request request = builder.build();
        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }

    public static String doPost(String host, String path, Map<String, String> headers, Map<String, String> querys, Map<String, String> bodys) throws IOException {
        OkHttpClient client = getUnsafeOkHttpClient();

        FormBody.Builder formBodyBuilder = new FormBody.Builder();
        if (bodys != null) {
            for (Map.Entry<String, String> entry : bodys.entrySet()) {
                formBodyBuilder.add(entry.getKey(), entry.getValue());
            }
        }
        RequestBody formBody = formBodyBuilder.build();

        Request.Builder builder = new Request.Builder();
        builder.url(buildUrl(host, path, querys));
        builder.post(formBody);
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            builder.addHeader(entry.getKey(), entry.getValue());
        }

        Request request = builder.build();
        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }

    public static String doPost(String host, String path, Map<String, String> headers, Map<String, String> querys, String body) throws IOException {
        OkHttpClient client = getUnsafeOkHttpClient();

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
        RequestBody requestBody = RequestBody.create(mediaType, body);

        Request.Builder builder = new Request.Builder();
        builder.url(buildUrl(host, path, querys));
        builder.post(requestBody);
        for (Map.Entry<String, String> entry : headers.entrySet()) {
            builder.addHeader(entry.getKey(), entry.getValue());
        }

        Request request = builder.build();
        try (Response response = client.newCall(request).execute()) {
            return response.body().string();
        }
    }

    private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
        StringBuilder sbUrl = new StringBuilder();
        sbUrl.append(host);
        if (path != null && !path.isEmpty()) {
            sbUrl.append(path);
        }
        if (querys != null && !querys.isEmpty()) {
            sbUrl.append("?");
            for (Map.Entry<String, String> entry : querys.entrySet()) {
                sbUrl.append(entry.getKey())
                        .append("=")
                        .append(URLEncoder.encode(entry.getValue(), "utf-8"))
                        .append("&");
            }
            sbUrl.deleteCharAt(sbUrl.length() - 1); // Remove the last "&"
        }
        return sbUrl.toString();
    }
}
